package com.cskaoyan.javase.array._4operation._3curd;

import java.util.Arrays;
import java.util.Scanner;

/**
 * 数组元素的增删改查
 * 数组是一个容器，可以用存放元素，存放数据。
 * 在实际开发中，工程中也会需要存放大量数据，这一般是通过数据库来实现的。
 * 实际开发的基本需求就是基于数据库的，对数据进行增删改查，即"crud"
 * 也有很多中低级Java程序员自嘲自己为"crud工程师"
 * 当然"crud"指的是：
 *      1.c，create：新增数据/增加。
 *      2.r，retrieve：检索数据/查询。
 *      3.u，update：更新数据/修改。
 *      4.d，delete ：删除数据/删除。
 *
 * 我们现在还没有学习过数据库，但是不重要。
 * 现在我们使用数组这个容器，来模拟数据库，实现日常开发中最常见的"crud"操作。
 *
 *
 * 需求：
 *      现在要求实现对一个"name数组"的增删改查
 *      name数组中存放很多姓名，但是不存在两个相同的姓名，姓名具有唯一性
 *
 * 在实现增删改查之前,先实现name数组元素的打印,要求:
 *      只显示真实的姓名,不显示数组中的null元素
 *
 * @since 17:00
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        String[] names = new String[10];
        names[0] = "张三";
        names[1] = "李四";
        names[2] = "王二";
        names[3] = "张麻子";
        names[4] = "坤坤";
        names[5] = "二狗";
        // 现在names数组中,有6个姓名对象,还有4个null
        // 先打印一下数组的真实名字
        printNames(names);
        Scanner sc = new Scanner(System.in);
        System.out.println("开始插入一个姓名:");
        String nameCreate = sc.nextLine();
        switch (createName(names, nameCreate)) {
            case 1:
                System.out.println("新增成功!");
                printNames(names);
                break;
            case 2:
                System.out.println("新增失败!数组满了!");
                printNames(names);
                break;
            case 3:
                System.out.println("新增失败!插入的名字重复了!");
                printNames(names);
                break;
        }
        System.out.println("开始删除一个姓名:");
        String nameDelete = sc.nextLine();
        if (deleteName(names, nameDelete)) {
            System.out.println("删除成功!");
            printNames(names);
        }else {
            System.out.println("删除失败!没找到目标元素!");
            printNames(names);
        }

    }

    // 打印name数组中的姓名,排除null元素
    public static void printNames(String[] names) {
        System.out.print("[");
        // 遍历打印姓名,排除null元素
        for (String name : names) {
            if (name == null) {
                continue;
            }
            System.out.print(name + ", ");
        }
        System.out.println("\b\b]");
    }

    // 往name数组中新增元素
    /*
        数组可不可能真的直接新增一个元素?
        数组长度不可变,不可能真的新增
        所以这里的新增,指的是找到一个null的位置,然后赋值

        分析一下该方法,该方法的执行有以下几种可能:
            1.新增成功.首先数组必须要有null的位置,新增的名字不重复
            2.新增失败,数组满了,没有null的位置了
            3.新增失败,因为新增的名字重复了.

       这个方法至少有三个结果,三种状态,可以返回一个状态码,来指示方法的执行结果.
       这里规定,方法返回:
            1,表示新增成功
            2,表示数组满了,新增失败
            3,表示插入的名字重复了,新增失败
     */

    /**
     * 方法返回:
     *  1,表示新增成功
     *  2,表示数组满了,新增失败
     *  3,表示插入的名字重复了,新增失败
     *
     * @param names 被新增名字的name数组
     * @param target 被新增的名字
     * @return int
     * @author wuguidong@cskaoyan.onaliyun.com
     * @since 2022/06/09 17:16
     */
    public static int createName(String[] names, String target) {
        // 1,判断target是否重复
        for (String name : names) {
            // 逐一比对字符串内容
            /*
                name是有可能等于null的,所以不要用它调用方法
                而target是键盘录入得到的,是永远不会等于null
                (键盘录入直接回车,得到空的字符串"")
                所以用target来调用方法会更好!
             */
            if (target.equals(name)) {
                // 说明重复了
                return 3;
            }
        }
        // 2,被插入的姓名不是重复的,开始进行插入操作
        for (int i = 0; i < names.length; i++) {
            // 找到一个null的位置
            if (names[i] == null) {
                // 找到了,赋值插入
                names[i] = target;
                // 插入成功
                return 1;
            }
        }
        // 如果代码运行到这里,说明没有找到null的位置,数组满足
        return 2;
    }


    // 删除姓名
    /*
        删除姓名是不可能真的删除的,因为数组长度不可变
        所以把一个名字,赋值为null,表示它被删除了
        分析,删除有以下结果:
            1.找到了目标姓名,删除成功
            2.没找到目标姓名,删除失败
     */

    /**
     * 方法的结果:
     *  找到了目标姓名,删除成功,返回true
     *  没找到目标姓名,删除失败,返回false
     *
     * @param names 被删除姓名的数组
     * @param target 被删除的姓名
     * @return boolean
     * @author wuguidong@cskaoyan.onaliyun.com
     * @since 2022/06/09 17:46
     */
    public static boolean deleteName(String[] names, String target) {
        // 遍历查找目标元素,找到了就用null覆盖,返回true,没找到直接返回false
        for (int i = 0; i < names.length; i++) {
            if (target.equals(names[i])) {
                // 找到了,置为null,删除成功
                names[i] = null;
                return true;
            }
        }
        // 没找到
        return false;
    }
}
